package jaux.tank.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;
import com.fasterxml.jackson.databind.ObjectMapper;

import jaux.tank.service.FaceRecognitionService;
import jaux.tank.service.system.AttachmentService;
import jaux.tank.service.system.IConstantFactory;
import jaux.tank.service.system.impl.ConstantFactory;

@Service
public class FaceRecognitionServiceBaiduImpl implements FaceRecognitionService {

	public static final String BAIDU_FACE_APP_ID = "BAIDU_FACE_APP_ID";
	public static final String BAIDU_FACE_API_KEY = "BAIDU_FACE_API_KEY";
	public static final String BAIDU_FACE_SECRET_KEY = "BAIDU_FACE_SECRET_KEY";
	public static final String FACE_MATCH_PASSLINE = "FACE_MATCH_PASSLINE";
	public static final double DEFAULT_FACE_MATCH_PASSLINE=80d;

	private static final Logger logger = LoggerFactory.getLogger(FaceRecognitionServiceBaiduImpl.class);
	
	ObjectMapper objectMapper = new ObjectMapper();
	
	@Autowired
	AttachmentService attachmentService;

	@Override
	public String detect(String picture, String pictureType) {
		/*
		 * 获取图片内容base64编码
		 */
		String base64 = null;
		if ("base64".equalsIgnoreCase(pictureType)) {
			base64 = picture;
		} else if ("attachment".equalsIgnoreCase(pictureType)) {
			byte[] pictureContent = null;
			try {
				pictureContent = attachmentService.getAttachmentContent(picture);
			} catch (IOException e) {
				logger.error("获取图片附件失败", e);
			}
			if (pictureContent != null)
				base64 = Base64Utils.encodeToString(pictureContent);
		}
		if (base64 == null) {
			return null;
		}
		IConstantFactory constant = ConstantFactory.me();
		// 初始化一个AipFace
		AipFace client = new AipFace(constant.getCfg(BAIDU_FACE_APP_ID), constant.getCfg(BAIDU_FACE_API_KEY),
				constant.getCfg(BAIDU_FACE_SECRET_KEY));

		// 可选：设置网络连接参数
		client.setConnectionTimeoutInMillis(10000);
		client.setSocketTimeoutInMillis(60000);
		// 传入可选参数调用接口
		HashMap<String, String> options = new HashMap<String, String>();
		options.put("face_field", "age");
		options.put("max_face_num", "2");
		options.put("face_type", "LIVE");
		options.put("liveness_control", "NONE");
		// 人脸检测
		JSONObject res = client.detect(base64, "BASE64", options);
		return res.toString();
	}

	@Override
	public String match(String picture1, String pictureType1, String picture2, String pictureType2) {
		/*
		 * 获取图片内容base64编码
		 */
		String pictures[] = new String[] {picture1, picture2};
		String[] pictureTypes = new String[] {pictureType1, pictureType2};
		return match(pictures, pictureTypes);
	}

	@Override
	public String match(String[] pictures, String[] pictureTypes) {
		/*
		 * 获取图片内容base64编码
		 */
		ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
		for(int i=0,len=pictures.length;i<len;i++) {
			String picture = pictures[i];
			String pictureType = pictureTypes[i];
			String base64 = null;
			if ("base64".equalsIgnoreCase(pictureType)) {
				base64 = picture;
			} else if ("attachment".equalsIgnoreCase(pictureType)) {
				byte[] pictureContent = null;
				try {
					pictureContent = attachmentService.getAttachmentContent(picture);
				} catch (IOException e) {
					logger.error("获取图片附件失败", e);
				}
				if (pictureContent != null)
					base64 = Base64Utils.encodeToString(pictureContent);
			}
			if (base64 == null) {
				continue;
			}
			MatchRequest req1 = new MatchRequest(base64, "BASE64");
			requests.add(req1);
		}
		if(requests.size()>1) {
			IConstantFactory constant = ConstantFactory.me();
			// 初始化一个AipFace
			AipFace client = new AipFace(constant.getCfg(BAIDU_FACE_APP_ID), constant.getCfg(BAIDU_FACE_API_KEY),
					constant.getCfg(BAIDU_FACE_SECRET_KEY));
			return client.match(requests).toString();
		}
		return null;
	}
	@Override
	public Boolean isSameFace(String[] pictures, String[] pictureTypes) {
		/*
		 * 进行人脸对比
		 */
		Map matchResult = null;
		try {
			matchResult = objectMapper.readValue(match(pictures, pictureTypes), Map.class);
		} catch (IOException e) {
			logger.error("解析人脸对比结果错误", e);
		}
		if(matchResult==null)
			return false;
		/*
		 * 读取人脸对比及格线
		 */
		IConstantFactory constant = ConstantFactory.me();
		String passlineCfg = constant.getCfg(FACE_MATCH_PASSLINE);
		Double passline = null;
		try {
			  passline = Double.parseDouble(passlineCfg);
		}catch(Exception e) {
			logger.warn("人脸对比合格线参数解析失败，将使用默认及格线进行验证", e);
		}
		if(passline == null) {
			passline = DEFAULT_FACE_MATCH_PASSLINE;
		}
		/*
		 * 根据比对成绩和及格线判定是否是同个人脸
		 */
		Map result = (Map)matchResult.get("result");
		if((Integer)matchResult.get("error_code")!=0) {
			logger.warn("人脸对比结果解析错误，error_code:"+matchResult.get("error_code"));
			return false;
		}
		Integer score =(Integer)result.get("score");
		return score>=passline;
		
		
	}
	
}
